﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Collections;

namespace ManagerMachine
{
    public partial class ManagerTable
    {
        Socket sock;
        IPAddress ipServer;
        int portServer;
        
        bool isStart;
        Hashtable Tables;
        CONFIG config;

        public ManagerTable(CONFIG config)
        {
            this.ipServer = IPAddress.Parse(config.IP_TABLE_SERVER);
            this.portServer = config.PORT_TABLE_SERVER;
            this.config = config;
            IPEndPoint endpoint = new IPEndPoint(ipServer,portServer);
            try
            {
                sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                sock.Bind(endpoint);
            }
            catch(Exception e)
            {

            }

            Init();
        }

        void Init()
        {            
            Tables = new Hashtable();
            isStart = false;
        }

        public void Start()
        {
            isStart = true;
            sock.Listen(config.MAX_TABLE);
            sock.BeginAccept(new AsyncCallback(AcceptUser), sock);        
            Print("Port to Table Connect Open at port = "+portServer.ToString()+"!");            
        }

        void AcceptUser(IAsyncResult ar)
        {
            try
            {
                if(!ar.IsCompleted)
                {
                    sock.BeginAccept(new AsyncCallback(AcceptUser), sock);
                    return;
                }
                Socket client = sock.EndAccept(ar);
                if (!CheckMaxConnect())
                {
                    client.Disconnect(true);
                    client = null;
                    sock.BeginAccept(new AsyncCallback(AcceptUser), sock);
                    return;
                }
                Table new_table = new Table(Tables.Count,client);
                Tables.Add(Tables.Count, new_table);               
                Print("New User Connected " + ((IPEndPoint)client.RemoteEndPoint).Port);
                if (NewTableConnected != null)
                    NewTableConnected(this, new TableConnectedEventArgs(new_table));
                sock.BeginAccept(new AsyncCallback(AcceptUser), sock);

            }
            catch (System.Exception e)
            {
            	
            }
        }

        public void RemoveClient(Table client)
        {
            int id = client.Table_ID;
            client = null;
            Tables.Remove(id);
        }

        void Print(string text)
        {
            Console.WriteLine(text);
        }

        bool CheckMaxConnect()
        {
            if (Tables.Count == config.MAX_TABLE)
                return false;
            return true;

        }

        public event EventHandler<TableConnectedEventArgs> NewTableConnected;
    }
}
